package com.starview.platform.data.type;

import com.starview.star.compiler.standard.StandardNames;
import com.starview.star.compiler.util.PrettyPrintDisplay;
import com.starview.star.compiler.util.PrettyPrintable;

@SuppressWarnings("serial")
public abstract class Quantifier implements PrettyPrintable
{
  private final TypeVar var;

  Quantifier(TypeVar var)
  {
    this.var = var;
  }

  public TypeVar getVar()
  {
    return var;
  }

  abstract public IType wrap(IType type);

  @Override
  public String toString()
  {
    return PrettyPrintDisplay.toString(this);
  }

  public static class Universal extends Quantifier
  {
    public Universal(TypeVar v)
    {
      super(v);
    }

    @Override
    public void prettyPrint(PrettyPrintDisplay disp)
    {
      disp.append(StandardNames.FOR_ALL);
      disp.appendId(getVar().getVarName());
    }

    @Override
    public IType wrap(IType type)
    {
      if (TypeUtils.isTypeVar(getVar()))
        return new UniversalType(getVar(), type);
      else
        return type;
    }
  }

  public static class Existential extends Quantifier
  {
    public Existential(TypeVar v)
    {
      super(v);
    }

    @Override
    public void prettyPrint(PrettyPrintDisplay disp)
    {
      disp.append(StandardNames.EXISTS);
      disp.appendId(getVar().getVarName());
    }

    @Override
    public IType wrap(IType type)
    {
      if (TypeUtils.isTypeVar(getVar()))
        return new ExistentialType(getVar(), type);
      else
        return type;
    }
  }
}
